package pl.shenlon.ga;

import java.util.Random;

import pl.shenlon.poker.game.GameState;

public class SimpleChromosome implements Genom {

	public static final Random rnd;

	static {
		rnd = new Random();
	}
	public static SimpleChromosome createRandomizedGenom() {
		return new SimpleChromosome(
				BehaviourPattern.createRandomizedBehaviourPattern());
	}

	private final BehaviourPattern behaviourPattern;

	public SimpleChromosome() {
		super();
		behaviourPattern = new BehaviourPattern();
	}

	public SimpleChromosome(BehaviourPattern pattern) {
		this(pattern.getPattern());
	}

	public SimpleChromosome(int[] genom) {
		super();
		behaviourPattern = new BehaviourPattern(genom);
	}

	public SimpleChromosome(SimpleChromosome genom) {
		this(genom.behaviourPattern.getPattern());
	}

	@Override
	public Genom copy() {
		return new SimpleChromosome(this);
	}

	@Override
	public boolean equals(Object other) {
		if (other != null && other instanceof SimpleChromosome) {
			SimpleChromosome that = (SimpleChromosome) other;
			if (this == that) {
				return true;
			}
			return behaviourPattern.equals(that.behaviourPattern);
		}
		return false;
	}

	@Override
	public BehaviourPattern getBehaviourPattern(GameState gameState) {
		return behaviourPattern;
	}

	@Override
	public boolean mutate(double mutationRate) {
		if (rnd.nextDouble() <= mutationRate) {
			int indexToSubstract = rnd.nextInt(behaviourPattern.getLength()), indexToAdd = rnd
					.nextInt(behaviourPattern.getLength());
			while (indexToAdd == indexToSubstract) {
				indexToAdd = rnd.nextInt(behaviourPattern.getLength());
			}

			int indexToSubstractValue = behaviourPattern
					.getValue(indexToSubstract);
			if (indexToSubstractValue > 0) {
				int indexToAddValue = behaviourPattern.getValue(indexToAdd);

				if (indexToSubstractValue / 2 > 0) {
					int difference = rnd.nextInt(indexToSubstractValue / 2);
					indexToSubstractValue -= difference;
					indexToAddValue += difference;

					behaviourPattern.setValue(indexToSubstract,
							indexToSubstractValue);
					behaviourPattern.setValue(indexToAdd, indexToAddValue);
				}
			}
			return true;
		}
		return false;
	}

	@Override
	public String toString() {
		return "SimpleGenom " + behaviourPattern.toString();
	}
}